package com.android.kotlin.repository

import android.arch.lifecycle.LiveData
import android.arch.lifecycle.MediatorLiveData
import android.support.annotation.MainThread
import android.util.Log
import com.android.kotlin.util.Resource
import com.android.kotlin.util.Status


abstract class NetworkRepository<ResultType> @MainThread
protected constructor() {
    //    // 调用该方法将 API 响应的结果保存到数据库中。
    //    @WorkerThread
    //    protected abstract void saveCallResult(@NonNull ResultType item);
    //查看是否已经有缓存
    private var isCache: Boolean = false

    // 返回一个代表 Resource 的 LiveData。
    val asLiveData: LiveData<Resource<ResultType>>
        get() = result

    private val result = MediatorLiveData<Resource<ResultType>>()

    private var dbSource: LiveData<ResultType>? = null


    // 调用该方法判断是否加载缓存内容
    @MainThread
    protected abstract fun shouldCache(): Boolean


    // 调用该方法从数据库中获取缓存数据。
    @MainThread
    protected abstract fun loadFromDb(): LiveData<ResultType>

    // 调用该方法创建 API 请求。
    @MainThread
    protected abstract fun createCall(): LiveData<Resource<ResultType>>

    // 获取失败时调用。
    @MainThread
    protected fun onFetchFailed() {
    }

    init {
        reload()
    }

    /**
     * 1.展示加载中
     * 2.加载本地数据
     * 3.判断是否需要加载网络（需要就加载网络数据，不需要就返回本地数据咯）
     */
    @MainThread
    fun reload() {
        result.setValue(Resource.loading(null))
        if(dbSource!=null){
            result.removeSource(dbSource!!)
        }
        dbSource = loadFromDb()

        fetchFromNetwork(dbSource!!)
    }

    private fun fetchFromNetwork(dbSource: LiveData<ResultType>) {
        val apiResponse = createCall()
        //判断是否加载缓存，如果需要，加载缓存
        if (shouldCache()) {
            result.addSource(
                dbSource
            ) { newData ->
                if (newData != null) {
                    isCache = true
                    result.setValue(Resource.success(newData))
                } else {
                    result.setValue(Resource.loading(null))
                }
            }
        }

        //请求网络数据
        result.addSource<Resource<ResultType>>(apiResponse) { response ->
            result.removeSource<Resource<ResultType>>(apiResponse)
            result.removeSource(dbSource)
            if (response?.status === Status.SUCCESS || response?.status === Status.EMPTY) {
                result.addSource<Resource<ResultType>>(apiResponse) { requestTypeResource ->
                    result.setValue(
                        requestTypeResource
                    )
                }
            } else {
                onFetchFailed()
                if (isCache) {//如果有缓存
                    Log.d("DaLongNet", "网络请求错误，有缓存，使用缓存的")
                } else {
                    Log.d("DaLongNet", "网络请求错误，没缓存，使用缓存的")
                    result.addSource(
                        dbSource
                    ) { newData ->
                        result.setValue(
                            Resource.error(response?.message, newData)
                        )
                    }
                }
            }
        }
    }

    companion object {
        protected var logTag = "network"
    }




}
